/**
 * API测试工具 (ESM版本)
 * 用于测试不同的API URL组合，找到正确的连接方式
 */

import fs from 'fs';
import path from 'path';
import http from 'http';
import https from 'https';
import { fileURLToPath } from 'url';

// 获取当前文件目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 加载配置
const loadConfig = () => {
    try {
        const configPath = path.join(__dirname, 'env.config');
        const content = fs.readFileSync(configPath, 'utf8');
        const config = {};

        content.split('\n').forEach(line => {
            if (line.trim().startsWith('#') || !line.trim()) return;

            const match = line.match(/^([A-Z0-9_]+)="([^"]*)"/);
            if (match) {
                const [, key, value] = match;
                config[key] = value;
            }
        });

        return config;
    } catch (error) {
        console.error('加载配置文件失败:', error);
        process.exit(1);
    }
};

// 配置项
const config = loadConfig();
console.log('原始API基础URL:', config.AUTO_API_BASE_URL);

// 测试API URL组合
const API_URL_VARIANTS = [
    {
        name: '原始URL',
        url: config.AUTO_API_BASE_URL,
    },
    {
        name: '不带子路径版本',
        url: config.AUTO_API_BASE_URL.replace(/\/autoapi$/, ''),
    },
    {
        name: '简化版本',
        url: `http://${new URL(config.AUTO_API_BASE_URL).hostname}:${new URL(config.AUTO_API_BASE_URL).port}/api`,
    },
    {
        name: '只用主机和端口',
        url: `http://${new URL(config.AUTO_API_BASE_URL).hostname}:${new URL(config.AUTO_API_BASE_URL).port}`,
    },
    {
        name: '替换tls为api',
        url: config.AUTO_API_BASE_URL.replace('/tls/', '/api/'),
    }
];

// 发送HTTP请求
const sendRequest = (url, method = 'GET', headers = {}, body = null) => {
    return new Promise((resolve, reject) => {
        try {
            const parsedUrl = new URL(url);
            const options = {
                hostname: parsedUrl.hostname,
                port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80),
                path: parsedUrl.pathname + parsedUrl.search,
                method: method,
                headers: {
                    'Content-Type': 'application/json',
                    ...headers
                },
                timeout: 5000 // 5秒超时
            };

            console.log(`发送${method}请求到: ${url}`);

            const client = parsedUrl.protocol === 'https:' ? https : http;
            const req = client.request(options, (res) => {
                let data = '';

                res.on('data', (chunk) => {
                    data += chunk;
                });

                res.on('end', () => {
                    console.log(`状态码: ${res.statusCode}`);

                    // 尝试解析JSON
                    let parsedData = null;
                    let parseError = null;

                    if (data) {
                        try {
                            parsedData = JSON.parse(data);
                            console.log('数据预览:', JSON.stringify(parsedData).substring(0, 100) + '...');
                        } catch (error) {
                            parseError = error;
                            console.log('数据不是有效的JSON:', data.substring(0, 100) + '...');
                        }
                    }

                    resolve({
                        statusCode: res.statusCode,
                        headers: res.headers,
                        data: parsedData,
                        rawData: data,
                        parseError: parseError
                    });
                });
            });

            req.on('error', (error) => {
                console.error(`请求失败: ${error.message}`);
                reject(error);
            });

            req.on('timeout', () => {
                console.error('请求超时');
                req.destroy();
                reject(new Error('请求超时'));
            });

            if (body) {
                req.write(typeof body === 'string' ? body : JSON.stringify(body));
            }

            req.end();
        } catch (error) {
            console.error(`创建请求失败: ${error.message}`);
            reject(error);
        }
    });
};

// 测试API端点
const testEndpoints = async (baseUrl) => {
    console.log(`\n=== 测试API基础URL: ${baseUrl} ===`);

    // 测试的端点列表
    const endpoints = [
        { path: '/ping', method: 'GET', label: 'Ping测试' },
        { path: '/get_token', method: 'POST', body: { project_id: config.PROJECT_ID }, label: '获取Token' },
        { path: '/tables', method: 'GET', query: `projectId=${config.PROJECT_ID}&schema=${config.SCHEMA_NAME}`, label: '获取表列表' },
        { path: '/projects', method: 'GET', label: '获取项目列表' },
        { path: '/schemas', method: 'GET', query: `projectId=${config.PROJECT_ID}`, label: '获取Schema列表' }
    ];

    let results = [];

    for (const endpoint of endpoints) {
        try {
            const url = baseUrl + endpoint.path + (endpoint.query ? `?${endpoint.query}` : '');
            console.log(`\n${endpoint.label}...`);

            const response = await sendRequest(url, endpoint.method, {}, endpoint.body);

            results.push({
                endpoint: endpoint.path,
                success: response.statusCode >= 200 && response.statusCode < 300 && !response.parseError,
                statusCode: response.statusCode,
                hasValidJson: !response.parseError
            });
        } catch (error) {
            console.error(`测试${endpoint.path}失败:`, error.message);
            results.push({
                endpoint: endpoint.path,
                success: false,
                error: error.message
            });
        }
    }

    return results;
};

// 获取令牌
const getToken = async (baseUrl) => {
    console.log(`\n=== 尝试从 ${baseUrl} 获取令牌 ===`);

    try {
        const url = `${baseUrl}/get_token`;
        const response = await sendRequest(url, 'POST', {}, { project_id: config.PROJECT_ID });

        if (response.statusCode >= 200 && response.statusCode < 300 && response.data && response.data.data && response.data.data.token) {
            const token = response.data.data.token;
            console.log('成功获取令牌!');

            // 保存令牌
            const tokenData = { token };

            // 保存到token.json
            const tokenPath = path.join(__dirname, 'token.json');
            fs.writeFileSync(tokenPath, JSON.stringify(tokenData, null, 2));
            console.log(`令牌已保存到: ${tokenPath}`);

            return token;
        } else {
            console.error('获取令牌失败:', response.statusCode, response.parseError ? '无效的JSON响应' : '');
            return null;
        }
    } catch (error) {
        console.error('获取令牌请求失败:', error.message);
        return null;
    }
};

// 使用令牌获取表列表
const getTableList = async (baseUrl, token) => {
    if (!token) {
        console.error('缺少令牌，无法获取表列表');
        return null;
    }

    console.log(`\n=== 使用令牌获取表列表 ===`);

    try {
        const url = `${baseUrl}/tables?projectId=${config.PROJECT_ID}&schema=${config.SCHEMA_NAME}`;
        const response = await sendRequest(url, 'GET', { 'Authorization': `Bearer ${token}` });

        if (response.statusCode >= 200 && response.statusCode < 300 && response.data) {
            console.log('成功获取表列表!');

            // 保存表列表
            const tablesDir = path.join(__dirname, '../raw-data');
            if (!fs.existsSync(tablesDir)) {
                fs.mkdirSync(tablesDir, { recursive: true });
            }

            const tablesPath = path.join(tablesDir, 'tables.json');
            fs.writeFileSync(tablesPath, JSON.stringify(response.data, null, 2));
            console.log(`表列表已保存到: ${tablesPath}`);

            return response.data;
        } else {
            console.error('获取表列表失败:', response.statusCode, response.parseError ? '无效的JSON响应' : '');
            return null;
        }
    } catch (error) {
        console.error('获取表列表请求失败:', error.message);
        return null;
    }
};

// 获取表结构
const getTableStructure = async (baseUrl, token, tableName) => {
    if (!token) {
        console.error('缺少令牌，无法获取表结构');
        return null;
    }

    console.log(`\n=== 获取表 "${tableName}" 的结构 ===`);

    try {
        const url = `${baseUrl}/columns?projectId=${config.PROJECT_ID}&schema=${config.SCHEMA_NAME}&table=${tableName}`;
        const response = await sendRequest(url, 'GET', { 'Authorization': `Bearer ${token}` });

        if (response.statusCode >= 200 && response.statusCode < 300 && response.data) {
            console.log(`成功获取表 "${tableName}" 的结构!`);

            // 保存表结构
            const tableDir = path.join(__dirname, '../raw-data', tableName);
            if (!fs.existsSync(tableDir)) {
                fs.mkdirSync(tableDir, { recursive: true });
            }

            const columnsPath = path.join(tableDir, 'columns.json');
            fs.writeFileSync(columnsPath, JSON.stringify(response.data, null, 2));
            console.log(`表结构已保存到: ${columnsPath}`);

            return response.data;
        } else {
            console.error(`获取表 "${tableName}" 结构失败:`, response.statusCode, response.parseError ? '无效的JSON响应' : '');
            return null;
        }
    } catch (error) {
        console.error(`获取表 "${tableName}" 结构请求失败:`, error.message);
        return null;
    }
};

// 主函数
const main = async () => {
    console.log('=== API测试开始 ===');
    console.log('项目ID:', config.PROJECT_ID);
    console.log('Schema:', config.SCHEMA_NAME);

    // 测试不同的API URL
    const resultsMap = {};

    for (const variant of API_URL_VARIANTS) {
        console.log(`\n===== 测试 ${variant.name}: ${variant.url} =====`);
        const results = await testEndpoints(variant.url);

        // 统计成功数
        const successCount = results.filter(r => r.success).length;
        console.log(`结果: ${successCount}/${results.length} 个端点成功`);

        resultsMap[variant.name] = {
            url: variant.url,
            successCount,
            totalCount: results.length,
            results
        };
    }

    // 找出最成功的URL
    const bestVariant = Object.values(resultsMap)
        .sort((a, b) => b.successCount - a.successCount)[0];

    if (bestVariant.successCount > 0) {
        console.log(`\n===== 最佳API URL: ${bestVariant.url} =====`);
        console.log(`成功率: ${bestVariant.successCount}/${bestVariant.totalCount}`);

        // 尝试获取令牌和表数据
        const token = await getToken(bestVariant.url);

        if (token) {
            const tables = await getTableList(bestVariant.url, token);

            if (tables && tables.tables && tables.tables.length > 0) {
                console.log(`\n找到 ${tables.tables.length} 个表`);

                // 获取前5个表的结构
                const sampleTables = tables.tables.slice(0, 5);
                for (const table of sampleTables) {
                    await getTableStructure(bestVariant.url, token, table.tableName);
                }

                // 保存最佳URL到env.config.js
                const configJsPath = path.join(__dirname, 'env.config.js');
                fs.writeFileSync(configJsPath, `
/**
 * 金牛座API文档与类型生成工具 - API配置
 * 从API测试中发现的最佳URL
 */
export default {
    AUTO_API_BASE_URL: "${bestVariant.url}",
    PROJECT_ID: "${config.PROJECT_ID}",
    SCHEMA_NAME: "${config.SCHEMA_NAME}"
};
`);
                console.log(`\n最佳API URL已保存到: ${configJsPath}`);
            }
        }
    } else {
        console.log('\n所有API URL测试都失败');
    }

    console.log('\n=== API测试完成 ===');
};

// 执行主函数
main().catch(error => {
    console.error('测试过程中发生错误:', error);
    process.exit(1);
}); 